import os
import sys
import time
import xml.etree.ElementTree as ET
from DrissionPage import ChromiumPage, ChromiumOptions
from bs4 import BeautifulSoup


def read_chrmoe_path():
    """
    读取chrome配置文件路径
    :return:
    """
    chrome_path = ''
    try:
        # 打开文件并读取内容
        with open(F'../../Config/chrome_path.txt', 'r', encoding='utf-8') as file:
            lines = file.readlines()
        # 遍历每一行，找到包含'chrome.exe'的行
        for line in lines:
            if 'chrome.exe' in line:
                chrome_path = line.strip()
                print(f'可执行文件路径读取成功：{chrome_path}')
                break
        return chrome_path
    except:
        print('未找到chrome_path可执行文件路径')


def chrom_page():
    """
    打开一个chrome浏览器
    :return: page对象
    """
    chrome_path = read_chrmoe_path()
    try:
        path = fr'{chrome_path}'
        co = ChromiumOptions().auto_port()
        co.set_browser_path(path)
        page = ChromiumPage(co)
        # 设置窗口最大化
        page.set.window.max()
        # 访问网页
        page.get('https://www.link114.cn/')
        return page
    except Exception as e:
        print(f'Chrome启动失败：{e}，请检查chrome_path路径是否正确。')
        return False


def login(page, username, password):
    try:
        page.ele("x://span[@class='floatright member_info']//a").click()  # 点击登录
        page.ele('@name=username').input(username)  # 账号
        time.sleep(2)
        page.ele('@name=passwd').input(password)  # 密码
        time.sleep(2)
        page.ele("x://*[@id='do_submit']").click()  # 点击登录按钮
        time.sleep(2)
        page.ele('x:/html/body/div[2]/a').click()  # 登录成功后进入主页
        time.sleep(2)
        return page
    except Exception as e:
        print(f'登录出现异常:{e}')
        return page


def split_txt_file(file_path, lines_per_file=500):
    """
    分割TXT到文件夹中
    :param file_path: 需要分割的TXT文件路径
    :param lines_per_file: 每个TXT中分割多少条数据
    :return: 包含完整路径的文件名列表
    """
    # 创建保存新文件的目录
    output_dir = f'split_txt_files_{lines_per_file}'
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)
    with open(file_path, 'r', encoding='utf-8') as file:
        lines = file.readlines()
        # 计算需要创建的新文件数量
    num_files = (len(lines) + lines_per_file - 1) // lines_per_file
    # 分割文件并保存
    file_names = []  # 初始化一个空列表来保存文件名
    for i in range(num_files):
        start_idx = i * lines_per_file
        end_idx = min((i + 1) * lines_per_file, len(lines))
        file_contents = lines[start_idx:end_idx]
        # 构建新文件的名称
        file_name = f'split_file_{i + 1}.txt'
        file_path_new = os.path.join(output_dir, file_name)
        with open(file_path_new, 'w', encoding='utf-8') as new_file:
            new_file.writelines(file_contents)
            # 将文件名添加到列表中
        file_names.append(file_name)
        # 输出中文并返回包含新文件名的列表
    print(f"分割完成。在'{output_dir}'目录中创建了 {num_files} 个新的txt文件。")
    return [f'{output_dir}/' + name for name in file_names]  # 返回包含完整路径的文件名列表


def read_txt_file(file_path):
    """
    读取TXT中的内容
    :param file_path: TXT文件路径
    :return: 文件内容
    """
    try:
        with open(file_path, 'r', encoding='utf-8') as file:
            content = file.read()
        return content
    except FileNotFoundError:
        # print(f"文件未找到：{file_path}")
        print(f"文件未找到：{file_path}")
        return None
    except Exception as e:
        print(f"读取文件时发生错误：{e}")
        return None


def load_config(xml_file):
    """
    解析XML配置文件，并返回元素的操作配置列表。
    :param xml_file: str，XML配置文件的路径。
    :return: list，包含所有元素的操作配置，每个配置为一个三元组 (name, xpath, enabled)。
    """
    tree = ET.parse(xml_file)  # 解析XML文件并获取根元素
    root = tree.getroot()
    actions = []  # 初始化一个空列表，用于存储所有元素的操作配置
    for elem in root.findall('element'):  # 遍历XML文件中所有的<element>元素
        name = elem.find('name').text  # 名称
        xpath = elem.find('xpath').text  # XPATH
        # 获取<element>中的<enabled>标签内容，判断是否启用点击操作
        enabled = elem.find('enabled').text.lower() == 'true'  # 将其转换为布尔值，'true' (不区分大小写) 为True，其余为False
        actions.append((name, xpath, enabled))  # 将名称、XPath路径和是否启用点击操作存储为一个元组，并添加到actions列表中
    # 返回包含所有元素配置的列表
    return actions


def click_tijiao(page, content, config_file):
    page.ele('x://*[@id="ip_websites"]').input(content, clear=True)  # 输入域名
    time.sleep(2)
    page.ele('x:/html/body/div[3]/div[1]/p[1]/span').click()  # 全选
    time.sleep(1)
    page.ele('x:/html/body/div[3]/div[1]/p[1]/span').click()  # 全选
    time.sleep(1)

    # 加载XML配置文件
    actions = load_config(config_file)
    # 遍历配置文件中的动作并执行
    for name, xpath, enabled in actions:
        if enabled:
            print(f"点击 {name} ({xpath})")  # 输出到控制台，方便调试
            element = page.ele(f'x:{xpath}')
            element.click()
            time.sleep(0.5)  # 根据需要添加延时

    page.ele('x://*[@id="tj"]/a').click()  # 点击提交按钮

    # 等待加载完成的循环
    while True:
        tbody_html = page.ele('x://*[@id="result_table"]/tbody').html
        soup = BeautifulSoup(tbody_html, "html.parser")
        all_tr = soup.find('tbody').find_all('tr')[1:]  # 排除表头
        loading_gif_found = False
        for tr in all_tr:
            for td in tr.find_all('td'):
                if '/template/images/loading.gif' in str(td):
                    loading_gif_found = True
                    break
            if loading_gif_found:
                break
        if not loading_gif_found:
            break
        time.sleep(3)


def click_recheck(page):
    """
    重查失败
    :param page:
    :return:
    """
    page.ele('x://*[@id="float_box"]/div[2]/a/span').click()  # 点击提交按钮
    time.sleep(3)

    tbody_html = page.ele('x://*[@id="result_table"]/tbody').html
    if '重查' in tbody_html or '失败' in tbody_html:
        while True:
            tbody_html = page.ele('x://*[@id="result_table"]/tbody').html
            soup = BeautifulSoup(tbody_html, "html.parser")
            all_tr = soup.find('tbody').find_all('tr')[1:]  # 排除表头
            # 检查所有td是否都不包含'/template/images/loading.gif'
            loading_gif_found = False
            for tr in all_tr:
                for td in tr.find_all('td'):
                    if '/template/images/loading.gif' in str(td):
                        loading_gif_found = True
                        break  # 如果找到，则跳出内层循环
                if loading_gif_found:
                    break  # 如果当前tr中有td包含指定字符串，则跳出外层循环
                else:
                    pass
            # 检查是否所有td都不包含'/template/images/loading.gif'
            if not loading_gif_found:
                break  # 如果所有td都不包含该字符串，则退出循环
            time.sleep(3)


def save_path(page):
    page.ele('x://*[@id="selectall"]/span').click()  # 点击全选
    time.sleep(2)
    mission = page.ele('x://*[@id="float_box"]/div[3]/a/span').click.to_download(save_path='./下载/',
                                                                                 rename=f'split_file_1')  # 点击导出
    mission.wait()
    time.sleep(5)


def main():
    page = chrom_page()
    config_path = '../../Config/config.xml'
    is_Login = True  # 代表需要登陆
    if is_Login:
        username = '1003206180'
        password = '1003206180'
        page = login(page, username, password)
        lines_per_file = 2000
    else:
        lines_per_file = 500
    txt_lists = split_txt_file('C:\\Users\\admin\Desktop\\500.txt', lines_per_file)
    for txt_path in txt_lists:
        content = read_txt_file(txt_path)
        print(f'正在查询:{txt_path}')
        click_tijiao(page, content, config_path)
        print(f'{txt_path}查询完成')
        print(f'正在重查:{txt_path}')
        click_recheck(page)
        print(f'{txt_path}重查完成')
        print(f'准备导出:{txt_path}')
        save_path(page)
        print(f'{txt_path}导出完成')


if __name__ == '__main__':
    main()
